package org.jivesoftware.spark.crowd.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.border.EmptyBorder;

import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.spark.PresenceManager;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.crowd.CrowdRecorder;
import org.jivesoftware.spark.crowd.CrowdsManager;
import org.jivesoftware.spark.crowd.Param;
import org.jivesoftware.spark.crowd.impl.Crowd;
import org.jivesoftware.spark.crowd.impl.Member;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.ChatRoomNotFoundException;
import org.jivesoftware.spark.ui.conferences.GroupChatParticipantList;
import org.jivesoftware.spark.ui.conferences.GroupChatParticipantList.ParticipantRenderer;
import org.jivesoftware.spark.ui.rooms.ChatRoomImpl;
import org.jivesoftware.spark.util.log.Log;

public class MemberListPane extends JPanel{
	/**
	 * 
	 */
	private static final long serialVersionUID = 19L;
	private JScrollPane scrollPanel;
	private JPanel listPanel;
	private JList memberList;
	private DefaultListModel listModel;
	
	
	private Crowd belongedCrowd;
	private JPopupMenu pop;
	public MemberListPane(String crowdName)throws Exception{
		this.belongedCrowd = CrowdsManager.getInstance().findCrowdByName(crowdName);
		if(belongedCrowd == null)
			throw new Exception("MemberListPane created error : no such crowd -- " + crowdName);
		listModel = new DefaultListModel();
		memberList = new JList(listModel);
		listPanel = new JPanel(new BorderLayout());
		
		this.setLayout(new BorderLayout());		
		this.setOpaque(false);
		this.setBackground(Color.white);
		this.setMinimumSize(new Dimension(150,0));
		
		
		listPanel.add(memberList,BorderLayout.CENTER);
		scrollPanel = new JScrollPane(listPanel);
		
		this.add(scrollPanel, BorderLayout.CENTER);
		
		listPanel.setBorder(new EmptyBorder(0,0,0,0));
		scrollPanel.setBorder(new EmptyBorder(0,0,0,0));
		this.setBorder(new EmptyBorder(0,0,0,0));
		initPopup();
			
		
		memberList.setCellRenderer(new CrowdMemberListRenderer());
		memberList.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent evt) {
				if (evt.getClickCount() == 2) {
					String selectedUser = getSelectedUser();
					startChat(selectedUser);
				}else if(evt.getButton() == 3){
					memberList.setSelectedIndex(memberList.locationToIndex(evt.getPoint()));
					pop.show(evt.getComponent(), evt.getX(), evt.getY());
				}
			}	
		});
		
	}
	private void initPopup(){
		pop = new JPopupMenu();
		Action chatAction = new AbstractAction(){
			@Override
			public void actionPerformed(ActionEvent e) {
				String selectedUser = getSelectedUser();
				startChat(selectedUser);
			}			
		};
		chatAction.putValue(Action.NAME, Param.getLabelText("singleChat", "发送消息"));
		Action removeAction = new AbstractAction(){
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub				
			}
			
		};
		removeAction.putValue(Action.NAME, Param.getLabelText("removeMember", "移除成员"));
		
		pop.add(chatAction);
		if(belongedCrowd.getCreator().getJID().equals(Param.getBareAddress())){
			pop.addSeparator();
			pop.add(removeAction);
		}
	}
	/**
	 * copy from {@link ParticipantRenderer}
	 * @author liyuan
	 *
	 */
	public static class CrowdMemberListRenderer extends JLabel implements ListCellRenderer {
		private static final long serialVersionUID = -7509947975798079141L;

		/**
		 * Construct Default JLabelIconRenderer.
		 */
		public CrowdMemberListRenderer() {
			setOpaque(true);
		}

		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			if (isSelected) {
				setBackground(list.getSelectionBackground());
				setForeground(list.getSelectionForeground());
			} else {
				setBackground(list.getBackground());
				setForeground(list.getForeground());
			}

			JLabel label = (JLabel) value;
			setText(label.getText());
			setIcon(label.getIcon());
			return this;
		}
	}
	private String getSelectedUser() {
		JLabel label = (JLabel) memberList.getSelectedValue();
		
		if (label != null) {
			return label.getText();
		}

		return null;
	}
	
	private void startChat(String nickName) {		
		Member m = belongedCrowd.FindMemberByNickName(nickName);
		String participantJID = m.getJID();
		if (nickName.equals(SparkManager.getUserManager().getNickname())) {
			return;
		}

		ChatRoom chatRoom;
		try {
			chatRoom = SparkManager.getChatManager().getChatContainer().getChatRoom(participantJID);
		} catch (ChatRoomNotFoundException e) {
			CrowdRecorder.record("Could not find chat room - " + nickName);
			
			// Create new room
			chatRoom = new ChatRoomImpl(m.getJID(), nickName, nickName);
			SparkManager.getChatManager().getChatContainer().addChatRoom(chatRoom);
		}

		SparkManager.getChatManager().getChatContainer().activateChatRoom(chatRoom);
	}
	/**
	 * 
	 * @param userIcon
	 * @param nickname
	 */
	
	public synchronized void addMember(Icon userIcon, String nickname,int index) {
		try {
			final JLabel member = new JLabel(nickname, userIcon,
					JLabel.HORIZONTAL);	
			listModel.insertElementAt(member, index);	
		} catch (Exception e) {
			Log.error(e);
		}
	}
	public synchronized void moveToFirst(Icon userIcon, String nickname){
		final JLabel member = new JLabel(nickname, userIcon,
				JLabel.HORIZONTAL);	
		
		int index = exists(nickname);
		if(index != -1){
			listModel.removeElementAt(index);
		}else return;
		if(listModel.size() >= 1 && ((JLabel)listModel.elementAt(0)).getText().equals(Param.getNickName())){
			listModel.insertElementAt(member, 1);
		}else{
			listModel.insertElementAt(member, 0);
		}
		this.validate();
		this.repaint();
		
	}
	
	public synchronized void moveToLast(Icon userIcon, String nickname){
		final JLabel member = new JLabel(nickname, userIcon,
				JLabel.HORIZONTAL);
		int index = exists(nickname);
		if(index != -1){
			listModel.remove(index);
		}else return;
		listModel.add(listModel.size(), member);
		this.validate();
		this.repaint();
	}
	public synchronized void updateIcon(Icon userIcon, String nickname){
		int index = exists(nickname);
		if(index != -1){
			JLabel label = (JLabel)listModel.getElementAt(index);
			label.setIcon(userIcon);
		}else return;
		this.validate();
		this.repaint();
	}
	
	
	/**
	 * 
	 * @param nickname
	 * @return
	 */
	public int exists(String nickname) {
		for (int i = 0; i < listModel.getSize(); i++) {
			final JLabel userLabel = (JLabel) listModel.getElementAt(i);
			if (userLabel.getText().equals(nickname)) {
				return i;
			}
		}
		return -1;
	}
	/**
	 * copy from {@link GroupChatParticipantList}
	 * @param name
	 * @return
	 */
	public int getIndex(String name) {
		for (int i = 0; i < listModel.getSize(); i++) {
			JLabel label = (JLabel) listModel.getElementAt(i);
			if (label.getText().equals(name)) {
				return i;
			}
		}
		return -1;
	}
	public DefaultListModel getListModel() {
		return listModel;
	}
	
	
	
	
}
